package component;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import pojo.TestBean;

/**
 * @author: ZhouBert
 * @date: 2020/9/17
 * @description:	测试 拓展点
 * 这个可以在创建对象之前进行干预，比如我想干坏事，
 * 我偷偷的找个地方加入一个TestInstantiationAwareBeanPostProcessor处理器，然后返回一个TestBean 的对象，
 * 这样别人就无法获取到userDao类型了。
 */
public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	/**
	 *
	 * 使用这个拓展返回了 一个实例不是 beanClass ，最后检查类型时会报错！
	 *
	 * AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
	 * 专门提供 InstantiationAwareBeanPostProcessor 接口进行处理！
	 * 那么这个拓展点的处理时机是什么时候呢？？？
	 * 在真正创建 bean 之前：即 doCreateBean 之前
	 * 如果通过 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation
	 * 完成了 bean 实例的返回，就直接用了！而跳过 doGetBean !!!
	 *
	 * 而 Spring 内部的 PersistenceAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor
	 * 默认返回 null 也就是不处理！
	 *
	 *
	 *
	 * @param beanClass the class of the bean to be instantiated
	 * @param beanName the name of the bean
	 * @return
	 * @throws BeansException
	 */
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		if(beanName.equals("myTestBean")){
			TestBean testBean = new TestBean();
			return testBean;
		}

		return null;
	}
}
